﻿using mozhi.smarterp.AuthorCenter.ApiMetadatas.Repositories;
using mozhi.smarterp.AuthorCenter.Permissions.PermissionApiGrants;
using mozhi.smarterp.AuthorCenter.Permissions.PermissionGrants;
using mozhi.smarterp.AuthorCenter.Permissions.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Guids;

namespace mozhi.smarterp.AuthorCenter.Permissions
{
    public class PermissionItemApiGrantAppService : AuthorCenterAppService, IPermissionItemApiGrantAppService
    {
        private IPermissionItemApiGrantRepository _reposiotry;
        private IGuidGenerator _guidGenerator;
        private IApiMetadataRepository _apiMetadataRepository;

        public PermissionItemApiGrantAppService(IPermissionItemApiGrantRepository repository , IGuidGenerator guidGenerator , IApiMetadataRepository apiMetadataRepository)
        {
            _reposiotry = repository;
            _guidGenerator = guidGenerator;
            _apiMetadataRepository = apiMetadataRepository;
        }

        public async Task<PermissionItemApiGrantDto> GetAsync(Guid id)
        {
            var entity = await _reposiotry.GetAsync(id);

            var dto = ObjectMapper.Map<PermissionItemApiGrant, PermissionItemApiGrantDto>(entity);

            await LoadDetailInfo(new List<PermissionItemApiGrantDto>() { dto});

            return dto;
        }

        public async Task<List<PermissionItemApiGrantDto>> GetListAsync(PermissionItemApiGrantFilter filter)
        {
            var entities = await _reposiotry.GetListAsync(null , filter.MaxResultCount , filter.SkipCount , null , filter.PermissionItemId);

            var dtos = ObjectMapper.Map<List<PermissionItemApiGrant>, List<PermissionItemApiGrantDto>>(entities);

            await LoadDetailInfo(dtos);

            return dtos;
        }

        public async Task<List<PermissionItemApiGrantDto>> CreateAsync(List<PermissionItemApiGrantCreateDto> inputs)
        {
            var entities = new List<PermissionItemApiGrant>();

            foreach (var input in inputs)
            {
                var entity = new PermissionItemApiGrant(_guidGenerator.Create() , input.PermissionItemId , input.ApiMetadataId);

                entities.Add(entity);
            }

            await _reposiotry.InsertManyAsync(entities);

            return ObjectMapper.Map<List<PermissionItemApiGrant>, List<PermissionItemApiGrantDto>>(entities);
        }

        public async Task<List<PermissionItemApiGrantDto>> UpdateAsync(Guid permissionItemId , List<PermissionItemApiGrantUpdateDto> inputs)
        {
            var entities = await _reposiotry.GetListAsync(null, int.MaxValue, 0, null, permissionItemId);
            var result = new List<PermissionItemApiGrant>();
            foreach (var input in inputs)
            {
                var entity = entities.FirstOrDefault(x => x.PermissionItemId == input.PermissionItemId && x.ApiMetadataId == input.ApiMetadataId);

                if (entity == null)
                {
                    entity = new PermissionItemApiGrant(_guidGenerator.Create(), input.PermissionItemId, input.ApiMetadataId);
                    await _reposiotry.InsertAsync(entity);
                }
                else
                {
                    entity.Change(input.PermissionItemId, input.ApiMetadataId);
                    await _reposiotry.UpdateAsync(entity);
                }
                result.Add(entity);
            }

            //移除不存在的值
            var removed = new List<PermissionItemApiGrant>();

            foreach(var entity in entities)
            {
                if(!inputs.Any(x=> x.PermissionItemId == entity.PermissionItemId && x.ApiMetadataId == entity.ApiMetadataId))
                    await _reposiotry.DeleteAsync(entity.Id);
            }

            return ObjectMapper.Map<List<PermissionItemApiGrant>, List<PermissionItemApiGrantDto>>(result);
        }

        public async Task DeleteAsync(Guid id)
        {
            await _reposiotry.DeleteAsync(id);
        }

        #region
        private async Task LoadDetailInfo(List<PermissionItemApiGrantDto> inputs)
        {
            var apiMetadataIds = inputs.Select(x=>x.ApiMetadataId).ToList();

            var apiMetadatas = await _apiMetadataRepository.GetListAsync();

            inputs.ForEach(input =>
            {
                var match = apiMetadatas.FirstOrDefault(x => x.Id == input.ApiMetadataId);
                input.ApiMetadataPath = match?.Method;
                input.ApiMetadataMethod = match?.Path;
            });
        }
        #endregion
    }
}
